#ifndef CM_FILE_H_
#define CM_FILE_H_

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

/* 这些函数存在的BUG:
 * 1、文件长度大于long所能表示的范围
 *
 */

static inline long cm_flength(FILE *file)
{
	long pos = ftell(file);
	fseek(file, 0, SEEK_END);
	long len = ftell(file);
	fseek(file, pos, SEEK_SET);

	return len;
}

static inline size_t cm_fread(const char *fname, char *data, size_t size)
{
	FILE* fp = NULL;
	fp = fopen(fname, "rb");
	if (fp == NULL)
		return 0;
	printf("file length is %ld\n", cm_flength(fp));
	size_t rl = fread(data, 1, size, fp);

	fclose(fp);
	return (rl);
}

static inline size_t cm_fwrite(const char *fname, const void *data, size_t size,
		int append)
{
	FILE* fp = NULL;
	fp = fopen(fname, append ? "ab" : "wb");
	if (fp == NULL)
		return 0;
	size_t rl = fwrite(data, 1, size, fp);

	fclose(fp);
	return (rl);
}

static inline int cm_file_exist(const char *path)
{
	if (path == NULL)
		return 0;
	if (access(path, F_OK) == 0)
		return 1;
	return 0;
}

static inline int cm_dir_exist(const char *path)
{
	if (path == NULL)
		return 0;

	DIR *dir = opendir(path);
	if (dir == NULL)
		return 0;

	closedir(dir);
	return 1;
}

static inline int cm_mkdir(const char *path)
{
	if (cm_file_exist(path)) {
		if (cm_dir_exist(path))
			return 0;
		else
			return -1; /* Exist, not a dir */
	}

	if (mkdir(path, 0700) != 0)
		return -1;
	else
		return 0;
}

static inline int create_multi_dir(const char *path)
{
	int i, len;

	len = strlen(path);
	char dir_path[len + 1];
	dir_path[len] = '\0';

	strncpy(dir_path, path, len);

	for (i = 0; i < len; i++) {
		if (dir_path[i] == '/' && i > 0) {
			dir_path[i] = '\0';
			if (access(dir_path, F_OK) < 0) {
				if (mkdir(dir_path, 0755) < 0) {
					return -1;
				}
			}
			dir_path[i] = '/';
		}
	}

	if (i == len) {
		if (access(dir_path, F_OK) < 0)
			if (mkdir(dir_path, 0755) < 0)
				return -1;
	}

	return 0;
}

#endif /* CM_FILE_H_ */
